package com.licheedev.serialtool.activity;

import android.app.Activity;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.widget.TextView;

import com.licheedev.serialtool.R;

import java.util.HashMap;
public class Test  extends Activity {
    private static final String TAG = "USB_HOST";
    private UsbManager myUsbManager;
    private UsbDevice myUsbDevice;
    private UsbInterface myInterface;
    private UsbDeviceConnection myDeviceConnection;
    private final int VendorID = 6790;//ch340 ;///1659;pl2303
    private final int ProductID = 29987;//ch340 //9155;pl2303
    private TextView info;
    private UsbEndpoint epOut;
    private UsbEndpoint epIn;
    private UsbEndpoint epControl;
    private UsbEndpoint epIntEndpointOut;
    private UsbEndpoint epIntEndpointIn;
    private UsbInterface Interface1;
    private UsbInterface Interface2;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        info = (TextView) findViewById(R.id.info);

        // 获取UsbManager
        myUsbManager = (UsbManager) getSystemService(USB_SERVICE);

        enumerateDevice();

        getDeviceInterface();

        openDevice();

        assignEndpoint( Interface2 );

        /**
         * 如果你的程序经过上面的四步运行得到下面的打印信息，说明你可以进行通讯处理了
         * 05-27 14:54:24.140: D/USB_HOST(10870): DeviceInfo: 8457 , 30264
         * 05-27 14:54:24.140: D/USB_HOST(10870): 枚举设备成功
         * 05-27 14:54:24.140: D/USB_HOST(10870): interfaceCounts : 1
         * 05-27 14:54:24.140: D/USB_HOST(10870): 找到我的设备接口
         * 05-27 14:54:24.160: D/USB_HOST(10870): 打开设备成功
         * 05-27 14:54:24.170: D/USB_HOST(10870): 到此为止：发现设备->枚举设备->找到设备的接口
         * 										->连接设备->分配相应的端点，都已完成，下一步可以进行通讯处理。。祝你好运！
         */


        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    receiveMessageFromPoint();
                    try {
                        Thread.sleep( 100 );
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    sendMessageToPoint( new byte[]{0x0e});
                    try {
                        Thread.sleep( 100 );
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();


    }

    /**
     * 分配端点，IN | OUT，即输入输出；此处我直接用1为OUT端点，0为IN，当然你也可以通过判断
     */
//    private void assignEndpoint() {
//        if( myInterface == null ) return;
//        if (myInterface.getEndpoint(1) != null) {
//            epOut = myInterface.getEndpoint(1);
//        }
//        if (myInterface.getEndpoint(0) != null) {
//            epIn = myInterface.getEndpoint(0);
//        }
//
//        Log.d(TAG, "通信");
//
//    }
    // 分配端点，IN | OUT，即输入输出；可以通过判断
    private UsbEndpoint assignEndpoint(UsbInterface mInterface) {

        for (int i = 0; i < mInterface.getEndpointCount(); i++) {
            UsbEndpoint ep = mInterface.getEndpoint(i);
            // look for bulk endpoint
            if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
                if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
                    epOut = ep;
                    System.out.println("Find the BulkEndpointOut," + "index:"
                            + i + "," + "使用端点号："
                            + epOut.getEndpointNumber());
                } else {
                    epIn = ep;
                    System.out
                            .println("Find the BulkEndpointIn:" + "index:" + i
                                    + "," + "使用端点号："
                                    + epIn.getEndpointNumber());
                }
            }
            // look for contorl endpoint
            if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_CONTROL) {
                epControl = ep;
                System.out.println("find the ControlEndPoint:" + "index:" + i
                        + "," + epControl.getEndpointNumber());
            }
            // look for interrupte endpoint
            if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_INT) {
                if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
                    epIntEndpointOut = ep;
                    System.out.println("find the InterruptEndpointOut:"
                            + "index:" + i + ","
                            + epIntEndpointOut.getEndpointNumber());
                }
                if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
                    epIntEndpointIn = ep;
                    System.out.println("find the InterruptEndpointIn:"
                            + "index:" + i + ","
                            + epIntEndpointIn.getEndpointNumber());
                }
            }
        }
        if (epOut == null && epIn == null && epControl == null
                && epIntEndpointOut == null && epIntEndpointIn == null) {
            throw new IllegalArgumentException("not endpoint is founded!");
        }
        return epIntEndpointIn;
    }

    // 发送数据
    private void sendMessageToPoint(byte[] buffer) {
        // bulkOut传输
        if (myDeviceConnection
                .bulkTransfer(epOut, buffer, buffer.length, 0) < 0)
            System.out.println("bulkOut返回输出为  负数");
        else {
            System.out.println("Send Message Succese！");
        }
    }
    // 从设备接收数据bulkIn
    private byte[] receiveMessageFromPoint() {
        byte[] buffer = new byte[1];
        if (myDeviceConnection.bulkTransfer(epIn, buffer, buffer.length,
                2000) < 0)
            System.out.println("bulkIn返回输出为  负数");
        else {
            System.out.println("Receive Message Succese！"
                     + "数据返回"
                     + String.format("%02x",buffer[0])
            );
        }
        return buffer;
    }
    /**
     * 打开设备
     */
    private void openDevice() {
        if (Interface2 != null) {
            UsbDeviceConnection conn = null;
            // 在open前判断是否有连接权限；对于连接权限可以静态分配，也可以动态分配权限，可以查阅相关资料
            if (myUsbManager.hasPermission(myUsbDevice)) {
                conn = myUsbManager.openDevice(myUsbDevice);
            }

            if (conn == null) {
                return;
            }

            if (conn.claimInterface(Interface2, true)) {
                myDeviceConnection = conn; // 到此你的android设备已经连上HID设备
                Log.d(TAG, "打开设备成功");
            } else {
                conn.close();
            }
        }
    }

    /**
     * 找设备接口
     */
//    private void findInterface() {
//        if (myUsbDevice != null) {
//            Log.d(TAG, "interfaceCounts : " + myUsbDevice.getInterfaceCount());
//            for (int i = 0; i < myUsbDevice.getInterfaceCount(); i++) {
//                UsbInterface intf = myUsbDevice.getInterface(i);
//                Log.e(Test.class.getSimpleName(),
//                        "intf====="+intf.getInterfaceClass()+"==="+
//                                intf.getInterfaceSubclass()+"=="+
//                                intf.getInterfaceProtocol()
//                );
//                if (intf.getInterfaceClass() == 255
//                // 根据手上的设备做一些判断，其实这些信息都可以在枚举到设备时打印出来
//                        && intf.getInterfaceSubclass() == 0
//                        && intf.getInterfaceProtocol() == 0) {
//                    myInterface = intf;
//                    Log.d(TAG, "找到我的设备接口");
//                }
//                break;
//            }
//        }
//    }
    // 寻找设备接口
    private void getDeviceInterface() {
        if (myUsbDevice != null) {
            Log.d(TAG, "interfaceCounts : " + myUsbDevice.getInterfaceCount());
            for (int i = 0; i < myUsbDevice.getInterfaceCount(); i++) {
                UsbInterface intf = myUsbDevice.getInterface(i);

                if (i == 0) {
                    Interface2 = Interface1 = intf; // 保存设备接口
                    System.out.println("成功获得设备接口:" + Interface1.getId());
                }
//                if (i == 1) {
//                    Interface2 = intf;
//                    System.out.println("成功获得设备接口:" + Interface2.getId());
//                }
            }
        } else {
            System.out.println("设备为空！");
        }

    }

    /**
     * 枚举设备
     */
    private void enumerateDevice() {
        if (myUsbManager == null)
            return;

        HashMap<String, UsbDevice> deviceList = myUsbManager.getDeviceList();
        if (!deviceList.isEmpty()) { // deviceList不为空
            StringBuffer sb;
            for (UsbDevice device : deviceList.values()) {
                sb = new StringBuffer();
                sb.append(device.toString());

                sb.append("\n");
                info.setText(sb);
                // 输出设备信息
                Log.d(TAG, "DeviceInfo: " + device.getVendorId() + " , "
                        + device.getProductId() + sb.toString() );

                // 枚举到设备
                if (device.getVendorId() == VendorID
                        && device.getProductId() == ProductID) {
                    myUsbDevice = device;
                    Log.d(TAG, "枚举设备成功");
                }
            }
        }
    }
}
